package com.mixsmart.commonweb.dao;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;

import com.mixsmart.commonweb.bean.IBaseTreeBean;
import com.mixsmart.commonweb.dao.impl.MenuDao;
import com.mixsmart.core.IMixSmart;
import com.mixsmart.core.xml.sqlmap.SqlMapUtils;
import com.mixsmart.core.xml.sqlmap.bean.SqlUnit;
import com.mixsmart.spellsql.utils.Cnd;
import com.mixsmart.spellsql.utils.Exp;
import com.mixsmart.utils.CollectionUtils;
import com.mixsmart.utils.StringUtils;

/**
 * 树形结构DAO
 * @author lmq
 * @version 1.0
 * @since JDK版本大于等于1.6
 * 2016年3月13日
 * @param <T>
 */
public class TreeDao<T extends IBaseTreeBean> extends SortNumDao<T> {

	private static final Logger logger = Logger.getLogger(MenuDao.class);
	
	/**
	 * 级联删除数据
	 * @param resName　资源名称（SQL语句名称）
	 * @param id 要删除的数据ID
	 * @return 如果删除成功，返回：true；否则返回false
	 * @throws DaoException
	 */
	public boolean cascadeRemove(String resName,String id) {
		boolean is = false;
		logger.debug("正在级联删除数据.....");
		if(StringUtils.isNotEmpty(id)) {
			String[] ids = id.split(IMixSmart.MULTI_VALUE_SPLIT);
			Set<String> delIdSet = new HashSet<String>();
			delIdSet.addAll(Arrays.asList(ids));
			this.getCascadeChildIds(delIdSet, ids);
			String[] delIdArray = new String[delIdSet.size()];
			delIdSet.toArray(delIdArray);
			SqlUnit sqlUtil = SqlMapUtils.getSql(resName);
			if(null != sqlUtil) {
				String[] delSqlArray = sqlUtil.getSql().split(IMixSmart.MULTI_STATEMENT_SPLIT);
				HashMap<String, Object> params = new HashMap<String, Object>();
				params.put("ids", delIdArray);
				for (String delSql : delSqlArray) {
					super.deleteSql(delSql, params);
				}
				delSqlArray = null;
			}
			is = true;
			logger.debug("级联删除数据---[成功]---");
		}
		return is;
	}
	
	/**
	 * 判断是否为叶子节点
	 * @param id 节点ID
	 * @return 如果是叶子节点；返回：true；否则返回：false
	 */
	public boolean isLeaf(String id) {
		return this.getChildNum(id)>0;
	}
	
	/**
	 * 获取子节点数
	 * @param id 子节点ID
	 * @return 返回子节点数，如果没有子节点，则返回：0
	 */
	public Long getChildNum(String id) {
		Long count = 0l;
		if(StringUtils.isNotEmpty(id)) {
			try {
				count = super.count(Cnd.where(Exp.eq("parentId", id)));
			} catch (Exception e) {
				count = 0l;
				e.printStackTrace();
			}
		}
		return count;
	}
	
	/**
	 *  级联获取所有子节点（针对树形结构表数据，递归查询）
	 * @param sets 存放查询出来的子节点ID的列表(Set集合)
	 * @param ids 要获取字节点的节点ID列表
	 * @throws NitccsException
	 */
	protected void getCascadeChildIds(Set<String> sets,String[] ids) {
		if(null == sets) {
			sets = new HashSet<String>();
		}
		String hql = "select id from "+super.entityClass.getName()+" where parentId in (:ids)";
		HashMap<String,Object> params = new HashMap<String, Object>();
		params.put("ids", ids);
		List<Object> listTmps = super.queryObjHql(hql, params);
		String[] idArray = removeRepeat(sets, listTmps);
		if(null != idArray && idArray.length>0) {
			if(null != idArray && idArray.length>0) {
				sets.addAll(Arrays.asList(idArray));
				getCascadeChildIds(sets, idArray);
			}
		}
	}
	
	/**
	 * 移除重复的数据
	 * @param sets 存放子节点ID集合
	 * @param childs 子节点ID
	 * @return 返回去重后的子节点ID数组
	 */
	private String[] removeRepeat(Set<String> sets, List<Object> childs) {
		String[] ids = null;
		if(CollectionUtils.isNotEmpty(sets) && CollectionUtils.isNotEmpty(childs)) {
			List<String> newChilds = new ArrayList<String>();
			for (Object child : childs) {
				if(!sets.contains(child.toString())) {
					newChilds.add(child.toString());
				}
			}
			ids = new String[newChilds.size()];
			newChilds.toArray(ids);
		}
		return ids;
	}
	
}
